快到鐵人賽尾聲了,這幾天找資料時發現這個沒提過的概念 - Utility Types,就讓我們來看一下這是什麼吧。
(這邊跟React沒有直接關係,你可以使用TypeScript遊樂場來實做看看,滿好玩的!)
簡單來說,Utility Types可以讓你用既有的型別、去創造出另一個型別。具體的實作方法,跟一般的函式很類似,我們接收一個"型別"當作input,最後以另外一個型別當成output輸出。之所以會有這個概念,是因為要輸出的型別,多少跟當作輸入的型別有一點關係,如果我們必須再次手動攥寫出一個類似型別,有點..失去了程式語言的初衷。目前官方提供的Utility Types多達22種,隨著版本的更新,仍在持續增加中。金天我們就來看幾個簡單、比較易用的吧!
Partial可以使我們所帶入的型別,其內部原本為必須的型別,通通都變成選擇性的。
假設我們有個Player
球員型別,所有的球員本來都必須有姓名、年紀、能力指標,而後來因各種因素,內部資訊已經不需要了,你就能將原本設定好的Player
型別,對他使用Partial,產生出一個全部都選擇性的型別。
type Player = {
name:string,
age:number,
ability:"Great" | "Average" | "Meh"
}
type NewPlayer = Partial<Player>
//a.k.a.
type NewPlayer = {
name?: string | undefined;
age?: number | undefined;
ability?: "Great" | "Average" | "Meh" | undefined;
}
既然Partial是將原本必須的型別改為選擇性,Required顧名思義就是相反的概念,將原本是選擇性的型別,改變成為必須的。
type Player = {
name: string,
age?: number,
ability?: "Great" | "Average" | "Meh"
}
type NewPlayer = Required<Player>
//a.k.a
type LittlePlayer = {
name: string;
age: number;
ability: "Great" | "Average" | "Meh";
}
Pick,翻成中文就是挑選嘛,我們會從要輸入的型別當中,挑選出我們想要的"鍵"(Keys),並產出一個新的型別。
type Player = {
name: string,
age?: number,
ability?: "Great" | "Average" | "Meh"
}
//這邊我還滿意外的,我以為要挑"A跟B",應該要是"&"這個符號
//沒想到在TypeScript內得用"|"這個符號
//但如果在JavaScript當中,我們可能會將"|"聯想到or去(還是只有我這樣?)
type NewPlayer = Pick<Player, "name" | "age">
//a.k.a.
//你會發現,就連age的選擇性也被選過來了
//所以我們要是後續有變動Player型別,NewPlayer就會跟著變動,很方便
type NewPlayer = {
name: string;
age?: number | undefined;
}
這個應該也是看名字就很好懂的,我們將Type輸入進Readonly,就能得到一個,內部所有屬性都不可再賦值的物件。
type Player = {
name: string
age: number
ability: "Great" | "Average" | "Meh"
}
const FrozenPlayer: Readonly<Player> = {
name: "John",
age: 18,
ability: "Great"
}
//下面這行就會出錯
//因為 'name' 為唯讀屬性,所以無法指派至 'name'。
FrozenPlayer.name = "Allen"
Omit,就是"遺漏;省略;刪去"。我們上面看過這麼多例子了,想必你一定也能猜出這在幹嘛。
我們選定一個Type,將內部其中一個(或多個鍵)給去除掉後,把剩下來的鍵值對當作新的型別來使用。
type Player = {
name: string
age: number
ability: "Great" | "Average" | "Meh"
}
//我們不管能力,球員會動就好
const RandomPlayer: Omit<Player, "ability"> = {
name: "John",
age: 20
}
//你若硬是要為RandomPlayer寫入ability,則會報錯!
//跟剛剛Pick的例子一樣,你要一次omit多個key,則用"|"寫入即可
TypeScript所提供的Utility Types有二十多個,我們不會、也沒必要在這邊看完,但你必須知道有這些東西的存在,日後回想起來、或者讀其他codebase時,不要被這些看似陌生的"型別"給嚇到,這篇文章的目的就達到了!
那我們最後一天再見!